home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-03-13 | 3.5 KB | 156 lines | [TEXT/CWIE] |
- /*----------------------------------------------------------------------------
-
- QuickSort.cp
-
- fastQSort() is a replacement for qsort(). Compared with the Think C library
- version of qsort, fastQSort is about 3 times faster (it takes 1/3 the time),
- and its speed isn't dependent on the data being sorted.
-
- One problem with qsort is that when the data is not in random order -- for
- example when it's already ordered, in reverse order, or almost sorted -- then
- qsort exhibits worst case behavior of N*N/2 operations. For N=1024 this can
- take about 30 seconds, instead of the usual 0.8 seconds. The fastQSort
- algorithm doesn't have this problem, because it randomly selects the pivot
- element, and so for N=1024 it requires about 0.26 secs +/- 0.02 secs.
-
- Also, because fastQSort doesn't exhibit worst case behavior, it doesn't
- require as much stack space, even though it has 12 bytes more of local
- variables.
-
- The things that make fastQSort so much faster than qsort are:
-
- 1) fastQSort picks the pivot element randomly, so it doesn't display worst
- case behavior.
-
- 2) fastQSort uses pointers and pointer arithmetic, avoiding multiplication
- whenever possible.
-
- 3) qsort uses std_swap() to swap the data between two locations, and
- std_swap loops through the data 3 times to perform the exchange! In
- comparison, swapMem() loops through the data just once.
-
- 4) fastQSort uses register variables whenever it makes good sense to do so.
-
-
- Researched and written by:
-
- Haydn Huntley
- Haydn's Consulting
- 203 West Stone
- Fairfield, Iowa 52556
- (515) 472-7025
-
- During the school year, I may be reached at the following address:
-
- Haydn Huntley
- Eigenmann Hall #289
- Indiana University
- Bloomington, IN 47406
- (812) 857-8620
-
- E-mail: huntley@copper.ucs.indiana.edu
-
- This version was modified by Randy Thelen of Apple Computer, Inc.
- This version works within the shell of SortPicts.
-
- Hopefully, we'll see faster Sorts with QuickSort than with Heap sorts and the like
- ----------------------------------------------------------------------------*/
-
- #include "SortPicts.h"
-
- void QSort( SortPicts *sortPicts)
- {
- sortPicts->QSort();
- }
-
-
- void SortPicts::QSort( void)
- {
- QuickSortEngine( 0, N);
- }
-
-
- void SortPicts::ChooseMedian( long a, long b, long c)
- {
- long m; // median
-
- if( sortData[a] > sortData[b])
- if( sortData[a] > sortData[c])
- if( sortData[b] > sortData[c])
- m = b;
- else
- m = c;
- else
- m = a;
- else
- if( sortData[a] > sortData[c])
- m = a;
- else
- if( sortData[b] > sortData[c])
- m = c;
- else
- m = b;
-
- if( a != m)
- ExchangeSortItem( a, m);
- }
-
-
- void SortPicts::QuickSortEngine( long left, long right)
- {
- long n;
- long i, j;
-
- while( (n = right - left) > 1)
- {
- if( n < kPivotCutoff) // Use a random pivot
- ExchangeSortItem( left + Random( n), left);
- else
- ChooseMedian( left, left + (n >> 1),
- left + Random( n));
-
- i = left;
- j = right;
-
- while( 1)
- {
- i++;
- while( (i < right) && (sortData[i] < sortData[left]))
- i++;
-
- j--;
- while( (j > left) && (sortData[j] > sortData[left]))
- j--;
-
- if( i >= j)
- break;
-
- ExchangeSortItem( i, j);
- }
-
- if( j == left)
- {
- left++;
- continue;
- }
-
- ExchangeSortItem( left, j);
- if( (j - left) < (right - (j + 1)))
- {
- /* equivalent to doFastQSort (j + qSize, last); */
- /* to save stack space */
- QuickSortEngine( left, j);
- left = j + 1;
- }
- else
- {
- /* equivalent to doFastQSort (first, j); */
- /* to save stack space */
- QuickSortEngine( j+1, right);
- right = j;
- }
-
- }
- }
-
-